﻿using Emgu.CV;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using BitMiracle.LibJpeg;
using Emgu.CV.Structure;
using Emgu.CV.Util;

namespace TestWPFEmguCV
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        //private const string video_url = "https://www.apple.com/105/media/us/iphone-x/2017/01df5b43-28e4-4848-bf20-490c34a926a7/films/feature/iphone-x-feature-tpl-cc-us-20170912_1920x1080h.mp4";
        private const string video_url = "rtsp://admin:zckj888888@192.168.1.64:554/h264/ch1/sub/av_stream";
        //private const string video_url = @"F:\GiteeSources\EasySpray201Beta\samples\Zane\SprayingRobot\bin\Debug\net6.0-windows\CameraVideo\2023-09-28114130.mp4";
        //private const string video_url = @"C:\Users\yyf\Downloads\192.168.1.64_01_20230928120511994.mp4";
        //private const string video_url = @"E:\Test\测试海康相机录制视频\WinFormsApp1\WinFormsApp1\bin\Debug\net6.0-windows\2023-09-28171917.mp4";
        //private const string video_url = "rtsp://admin:@192.168.1.62:554/h264/ch1/sub/av_stream";

        VideoCapture capture;

        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = MainWindowViewModel.Instance;
        }

      

        private void Window_Loaded(object sender, EventArgs e)
        {
            Task.Run(() =>
            {
                //capture = new VideoCapture(video_url);
                //capture.ImageGrabbed += Capture_ImageGrabbed;
                //capture.Grab();
                //capture.Start();

            });
           
            //capture.Read(Emgu.CV.CvEnum.CapProp.Fps);
            //label1.Text = capture.GetCaptureProperty(Emgu.CV.CvEnum.CapProp.Fps);
        }

        private void Btn方式一_OnClick(object sender, RoutedEventArgs e)
        {
            capture = new VideoCapture(video_url);
            capture.ImageGrabbed += Capture_ImageGrabbedWay1;
            capture.Grab();
            capture.Start();
        }

        private void Btn方式二_OnClick(object sender, RoutedEventArgs e)
        {
            capture = new VideoCapture(video_url);
            capture.ImageGrabbed += Capture_ImageGrabbedWay2;
            capture.Grab();
            capture.Start();
        }

        private void Btn方式三_OnClick(object sender, RoutedEventArgs e)
        {
            capture = new VideoCapture(video_url);
            capture.ImageGrabbed += Capture_ImageGrabbedWay3;
            capture.Grab();
            capture.Start();
        }

        int fps = 0;
        DateTime startTime = DateTime.Now;

        private void Capture_ImageGrabbed(object sender, EventArgs e)
        {
            
            fps++;
            Mat image = new Mat();
            capture.Retrieve(image);
            #region 使用EmguCV自带的转换为Byte
            string filename = "100.bmp";
            filename = "100.png";
            filename = "100.jpg";
            string ext = new FileInfo(filename).Extension;
            var d=MatToBmp.GetBytesByMat(image, ext);
            File.WriteAllBytes(filename, d);
           
            #endregion


            //image.Save("2.jpg");
            if (MainWindowViewModel.Instance.IsUseBingding)
            {
               
                //使用自己写的方法解析
                var cs = image.GetData();
                Byte[,,] data = cs as Byte[,,];
                byte[] bytes = MatToBmp.GetBMPFromYuv(data, image.Width, image.Height);
                MainWindowViewModel.Instance.Bytes = bytes;
                //this.Dispatcher.Invoke(() =>
                //{
                //    MainWindowViewModel.Instance.Bitmap = image.ToBitmapSource();

                //});
                File.WriteAllBytes("1.bmp", bytes);
            }
            else
            {
                //使用带UI线程的EmguCV
                this.Dispatcher.Invoke(() =>
                {
                    picCAM.Source = image.ToBitmapSource();
                });
            }
           
            //var bytes = new byte[image.Width*image.Height * 3];//这里必须乘以通道数，不然数组越界，也可以用w*h*c，差不多
            //Marshal.Copy(image.Total, bytes, 0, bytes.Length);

           
           
            TimeSpan ts = DateTime.Now - startTime;
            if (ts.TotalSeconds > 1)
            {
                startTime = DateTime.Now;
                int c = fps;
                this.Dispatcher.Invoke(new Action(() =>
                {
                    label1.Content = c;
                }));
                fps = 0;

            }

        }

        private void Capture_ImageGrabbedWay1(object sender, EventArgs e)
        {

            fps++;
            Mat image = new Mat();
            capture.Retrieve(image);
            string filename = "100.bmp";
            filename = "100.png";
            filename = "100.jpg";
            filename = "100.bmp";
            string ext = new FileInfo(filename).Extension;
            DateTime beginTime=DateTime.Now;
            var bytes = MatToBmp.GetBytesByMat(image, ext);
            TimeSpan tsConvertTime= DateTime.Now - beginTime;


            MainWindowViewModel.Instance.Bytes = bytes;

            TimeSpan ts = DateTime.Now - startTime;
            if (ts.TotalSeconds > 1)
            {
                startTime = DateTime.Now;
                int c = fps;
                this.Dispatcher.Invoke(new Action(() =>
                {
                    label1.Content = c;
                }));
                fps = 0;

            }

        }

        private void Capture_ImageGrabbedWay2(object sender, EventArgs e)
        {

            fps++;
            Mat image = new Mat();
            capture.Retrieve(image);
            var cs = image.GetData();
            Byte[,,] data = cs as Byte[,,];
            DateTime beginTime = DateTime.Now;
            byte[] bytes = MatToBmp.GetBMPFromYuv(data, image.Width, image.Height);
            TimeSpan tsConvertTime= DateTime.Now - beginTime;
            //DateTime time=DateTime.Now;
            //bytes = MatToBmp.GetJpjByBmpUseSixLab(bytes);
            //TimeSpan ts2= DateTime.Now - time;
            //File.WriteAllBytes("1.bmp", bytes);
            MainWindowViewModel.Instance.Bytes = bytes;

            //MainWindowViewModel.Instance.Bytes = bytes;

            TimeSpan ts = DateTime.Now - startTime;
            if (ts.TotalSeconds > 1)
            {
                startTime = DateTime.Now;
                int c = fps;
                this.Dispatcher.Invoke(new Action(() =>
                {
                    label1.Content = c;
                }));
                fps = 0;

            }

        }

        private void Capture_ImageGrabbedWay3(object sender, EventArgs e)
        {

            fps++;
            Mat image = new Mat();
            capture.Retrieve(image);
            this.Dispatcher.Invoke(() =>
            {
                picCAM.Source = image.ToBitmapSource();
            });

            TimeSpan ts = DateTime.Now - startTime;
            if (ts.TotalSeconds > 1)
            {
                startTime = DateTime.Now;
                int c = fps;
                this.Dispatcher.Invoke(new Action(() =>
                {
                    label1.Content = c;
                }));
                fps = 0;

            }

        }

        private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
        {
            //Bitmap bitmap = new Bitmap(@"F:\海康摄像头\新建文件夹\2.bmp");
            
            //Emgu.CV.Image<Bgr, UInt16> ImageEmgu = new Image<Bgr, UInt16>(bitmap.Width, bitmap.Height);
            //ImageEmgu = BitmapExtension.ToImage<Bgr, UInt16>(bitmap);
            //Mat image = ImageEmgu.Mat;
            Mat image = new Mat(@"F:\海康摄像头\新建文件夹\2.bmp");
            string filename = "5.bmp";
            Byte[] bytes = File.ReadAllBytes(@"F:\海康摄像头\新建文件夹\2.bmp");
            using (VectorOfByte buf = new VectorOfByte())
            {
                string ext = new FileInfo(filename).Extension;
                ext = ".jpg";
                //ext = ".png";

                CvInvoke.Imencode(ext, image, buf, null);
                byte[] array = buf.ToArray();
                File.WriteAllBytes(filename, array);
            }

            //image.ConvertTo(image, Emgu.CV.CvEnum.DepthType.Cv8U);
            //image.Save(@"F:\海康摄像头\新建文件夹\100.bmp");
        }

        private void ButtonBase2_OnClick(object sender, RoutedEventArgs e)
        {
            Byte[] bytes = File.ReadAllBytes(@"F:\海康摄像头\新建文件夹\2.bmp");
            DateTime startTime = DateTime.Now;
            Stream stream = new MemoryStream(bytes);
            Bitmap bitmap = new Bitmap(stream);
            
            Emgu.CV.Image<Bgr, UInt16> ImageEmgu = new Image<Bgr, UInt16>(bitmap.Width, bitmap.Height);
            ImageEmgu = BitmapExtension.ToImage<Bgr, UInt16>(bitmap);
            Mat image = ImageEmgu.Mat;

            IInputArray input = new VectorOfByte(bytes);
            //IInputArray output = new BitmapRgb565Image();
            //BitmapRgb565Image


            //Mat image = new Mat(@"F:\海康摄像头\新建文件夹\2.bmp");
            string filename = "7.jpg";
            
            using (VectorOfByte buf = new VectorOfByte())
            {
                string ext = new FileInfo(filename).Extension;
                ext = ".jpg";
                //ext = ".png";

                CvInvoke.Imencode(ext, image, buf, null);
                byte[] array = buf.ToArray();
                TimeSpan timeSpan = DateTime.Now - startTime;
                MessageBox.Show($"消耗时间({timeSpan.TotalMilliseconds})");
                File.WriteAllBytes(filename, array);
            }

            //image.ConvertTo(image, Emgu.CV.CvEnum.DepthType.Cv8U);
            //image.Save(@"F:\海康摄像头\新建文件夹\100.bmp");
        }

        private void ButtonBase3_OnClick(object sender, RoutedEventArgs e)
        {
            Byte[] bytes = File.ReadAllBytes(@"7.jpg");
            Stream stream = new MemoryStream(bytes);
            var c = JpegBitmapDecoder.Create(stream, BitmapCreateOptions.None, BitmapCacheOption.None);

            //new BitMiracle.LibJpeg.Classic.
         //   JpegImage img = new JpegImage(stream);
           
           DateTime startTime = DateTime.Now;
            
           
        }

        private void ButtonBase4_OnClick(object sender, RoutedEventArgs e)
        {
            Byte[] bytes = File.ReadAllBytes(@"1.bmp");
            DateTime startTime=DateTime.Now;
           var result= MatToBmp.GetJpjByBmpUseSixLab(bytes);
           TimeSpan ts=DateTime.Now - startTime;
           File.WriteAllBytes("SixLab.jpg", result);
        }

        private void ButtonBase5_OnClick(object sender, RoutedEventArgs e)
        {
            //未能成功
            Byte[] bytes = File.ReadAllBytes(@"Portable.bmp");
            Stream stream=new MemoryStream(bytes);
            //BitMiracle.LibJpeg.Classic.
            Bitmap bitmap = new Bitmap(stream);
            JpegImage jpegImage =  new JpegImage(stream);
            MemoryStream streamOutput = new MemoryStream();

            jpegImage.WriteBitmap(streamOutput);
            var result= streamOutput.GetBuffer();

            DateTime startTime = DateTime.Now;
            TimeSpan ts = DateTime.Now - startTime;
            File.WriteAllBytes("Portable.bmp", result);

        }
    }
}
